package net.zio.kamenriderzioaddon.ridersystem.util;

import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.level.Level;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.event.world.WorldEvent;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.function.Consumer;

/**
 * 延迟任务类
 *
 * @author QianYunYi
 *
 * 该类用于在服务器端延迟执行任务。
 */
public class DelayedTask {
    private static final Map<ServerLevel, Queue<Task>> TASK_MAP = new ConcurrentHashMap<>();
    private static boolean handlerRegistered = false;

    static {
        registerHandler();
    }

    // 注册事件处理程序
    private static void registerHandler() {
        if (!handlerRegistered) {
            MinecraftForge.EVENT_BUS.register(new DelayedTaskHandler());
            MinecraftForge.EVENT_BUS.register(new WorldUnloadHandler());
            handlerRegistered = true;
        }
    }

    /**
     * 运行延迟任务
     *
     * @param level      任务所在的服务器世界
     * @param delayTicks 延迟的游戏刻数
     * @param task       延迟执行的任务
     */
    public static void run(Level level, int delayTicks, Runnable task) {
        run(level, delayTicks, (l) -> task.run());
    }

    /**
     * 运行延迟任务
     *
     * @param level      任务所在的服务器世界
     * @param delayTicks 延迟的游戏刻数
     * @param task       延迟执行的任务
     */
    public static void run(Level level, int delayTicks, Consumer<Level> task) {
        if (level.isClientSide || !(level instanceof ServerLevel serverLevel)) {
            return;
        }

        TASK_MAP.computeIfAbsent(serverLevel, k -> new ConcurrentLinkedQueue<>())
                .add(new Task(delayTicks, task));
    }

    /**
     * 延迟任务类
     *
     * @author QianYunYi
     *
     * 该类用于表示延迟执行的任务。
     */
    private static class Task {
        private int ticksRemaining;
        private final Consumer<Level> action;

        public Task(int delay, Consumer<Level> action) {
            this.ticksRemaining = delay;
            this.action = action;
        }

        public boolean tick(ServerLevel level) {
            if (--ticksRemaining <= 0) {
                action.accept(level);
                return true;
            }
            return false;
        }
    }

    /**
     * 延迟任务处理类
     *
     * @author QianYunYi
     *
     * 该类用于处理延迟任务的事件。
     */
    private static class DelayedTaskHandler {
        @SubscribeEvent
        public void onServerTick(TickEvent.ServerTickEvent event) {
            if (event.phase == TickEvent.Phase.END) {
                for (Map.Entry<ServerLevel, Queue<Task>> entry : TASK_MAP.entrySet()) {
                    ServerLevel level = entry.getKey();
                    Queue<Task> tasks = entry.getValue();

                    // 使用迭代器安全处理
                    Iterator<Task> iterator = tasks.iterator();
                    while (iterator.hasNext()) {
                        Task task = iterator.next();
                        if (task.tick(level)) {
                            iterator.remove();
                        }
                    }
                }
            }
        }
    }

    /**
     * 世界卸载处理类
     *
     * @author QianYunYi
     *
     * 该类用于处理世界卸载事件。
     */
    private static class WorldUnloadHandler {
        @SubscribeEvent
        public void onWorldUnload(WorldEvent.Unload event) {
            if (event.getWorld() instanceof ServerLevel serverLevel) {
                TASK_MAP.remove(serverLevel);
            }
        }
    }
}